﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using Core.DataAccess.IRepositories;

namespace Core.DataAccess.Repositories
{
    [Export(typeof(ILocationRepository))]
    public class LocationRepository : ILocationRepository
    {
        private Connection conn;

        public LocationRepository()
        {
            conn = new Connection();
        }

        public void SaveLocation(Location location)
        {
            using (MXHEntities context = new MXHEntities())
            {
                if (location.LocationID > 0)
                {
                    context.Locations.Attach(new Location() { LocationID = location.LocationID });
                    context.Locations.ApplyCurrentValues(location);
                }
                else
                {
                    context.Locations.AddObject(location);
                }
                context.SaveChanges();
            }
        }

        public List<Location> GetLocationListByAccountID(Int32 accountID)
        {
            using (MXHEntities context = new MXHEntities())
            {
                var locations = from l in context.Locations
                                join al in context.AccountLocations on l.LocationID equals al.LocationID
                              join a in context.Accounts on al.AccountID equals a.AccountID
                              where a.AccountID == accountID
                              select l;
                List<Location> lst = locations.Count() > 0 ? locations.ToList() : null;
                return lst;
            }
        }

        public Location GetLocationByLocationID(Int32 locationID)
        {
            using (MXHEntities context = new MXHEntities())
            {
                return context.Locations.Where(l => l.LocationID.Equals(locationID)).SingleOrDefault();
            }
        }

        public Location GetLocationByLocationName(string locationName)
        {
            using (MXHEntities context = new MXHEntities())
            {
                return context.Locations.Where(l => l.LocationName.Equals(locationName)).SingleOrDefault();
            }
        }

        public void SaveAccountLocation(AccountLocation al)
        {
            using (MXHEntities context = new MXHEntities())
            {
                if (al.ALID > 0)
                {
                    context.AccountLocations.Attach(new AccountLocation() { ALID = al.ALID });
                    context.AccountLocations.ApplyCurrentValues(al);
                }
                else
                {
                    context.AccountLocations.AddObject(al);
                }
                context.SaveChanges();
            }
        }

        public List<AccountLocation> GetAccountLocationByUsername(string username)
        {
            using (MXHEntities context = new MXHEntities())
            {
                var locations = from l in context.AccountLocations.Include("Location")
                                join a in context.Accounts on l.AccountID equals a.AccountID
                                where a.Username == username
                                select l;

                return locations.ToList();
            }
        }

        public List<AccountLocation> GetAccountLocationByAccountID(Int32 accountID)
        {
            using (MXHEntities context = new MXHEntities())
            {
                var lo = from loca in context.AccountLocations
                         where loca.AccountID == accountID
                         select loca;
                List<AccountLocation> lst = lo.Count() > 0 ? lo.ToList() : null;
                return lst;
            }
        }

        public List<Account> GetAllFriendsLocationByAccountID(int accountID, string locationName)
        {
            List<Account> lstAccount = new List<Account>();            

            using (MXHEntities context = conn.GetContext())
            {
                var accounts = (from acc in context.Accounts
                               join aloca in context.AccountLocations on acc.AccountID equals aloca.AccountID
                               join loca in context.Locations on aloca.LocationID equals loca.LocationID
                               where loca.LocationName.Contains(locationName)
                               select acc).Distinct();                
                lstAccount = accounts.ToList();                
                int index = lstAccount.FindIndex(n => n.AccountID == accountID);
                lstAccount.RemoveAt(index);                                                
            }

            return lstAccount;
        }

        public int UpdateLocationInfo(int accountID, Location location)
        {
            using (MXHEntities context = conn.GetContext())
            {
                var item = from lo in context.Locations
                           join acclo in context.AccountLocations on lo.LocationID equals acclo.LocationID
                           where acclo.AccountID == accountID
                           select lo;
                if (item.Count() > 0)
                {
                    Location update = item.FirstOrDefault();
                    update.LocationName = location.LocationName;
                    update.Address = location.Address;
                    update.City = location.City;
                    update.Country = location.Country;
                    context.SaveChanges();
                    return 0;
                }
                context.Locations.AddObject(location);
                context.SaveChanges();
                return location.LocationID;
            }
        }

        public int UpdateAccountLocationInfo(int accountID, AccountLocation accLocation, int locationID)
        {
            using (MXHEntities context = conn.GetContext())
            {
                var item = from acclo in context.AccountLocations
                           where acclo.AccountID == accountID
                           select acclo;
                if (item.Count() > 0)
                {
                    AccountLocation update = item.FirstOrDefault();
                    update.StartDate = accLocation.StartDate;
                    update.EndDate = accLocation.EndDate;
                    context.SaveChanges();
                    return 0;
                }
                AccountLocation newAcc = new AccountLocation();
                newAcc.AccountID = accountID;
                newAcc.LocationID = locationID;
                newAcc.StartDate = accLocation.StartDate;
                newAcc.EndDate = accLocation.EndDate;
                context.AccountLocations.AddObject(newAcc);
                context.SaveChanges();
                return 1;
            }
        }
    }
}
